<?php

/**
 * Library.php
 *
 * Holds class Library
 *
 * @package Library
 */

define("LIBDIST", LIB."dist".DIRECTORY_SEPARATOR);

/**
 * Library
 *
 * Library bootstrap class
 *
 * @package Library
 */
final class Library {

	private $distList;

	/**
	 * Constructor
	 *
	 * @return void
	 */
	public function __construct() {
		set_error_handler("LibraryErrorHandler",E_ALL);

		spl_autoload_register(array($this, 'load'));
		//Util::dummy();

		// 		$this->setup();
	}

	public function setup(){
		$source = LIBDIST;
		$sourceSerFile = $source ."list";
		$sourceSer = (file_exists($source . "list") ? unserialize(file_get_contents($sourceSerFile)) : null);

		if(null == $sourceSer){
			$sourceSer = $this->readFolderRecursive($source);

			file_put_contents($sourceSerFile, serialize($sourceSer));
		}

		$this->distList = $sourceSer;

		return $sourceSer;
	}

	public function createApplication($list, $dirTarget = APP, $dirSource = LIBDIST){
		if(is_array($list)){
			foreach($list as $key => $a){
				$this->createApplication(
				$a,
				$dirTarget . (is_array($a) ? $key . DIRECTORY_SEPARATOR : ""),
				$dirSource . (is_array($a) ? $key . DIRECTORY_SEPARATOR : "")

				);
			}
		}else{
			$source = $dirSource.$list;
			$target = $dirTarget.$list;

			$target = str_replace(".dist", "", $target);

			if(!file_exists($target)){
				try{
					echo "from: {$source} to: {$target}\n";

					$this->mk_dir($dirTarget);

					copy($source, $target);
				}catch(Exception $e){
					echo "Could not create file {$target}<br />\n";
				}
			}
		}
	}

	/**
	 * Library autoloader
	 *
	 * @param string $class
	 * @return boolean
	 */
	public static function load($class) {
		$file = rtrim(dirname(__FILE__), '\\/' . DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
		if(file_exists($file)) {
			require_once $file;
			return true;
		}
		return false;
	}

	private function readFolderRecursive($dir = "root_dir/dir")
	{
		$listDir = array();
		if($handler = opendir($dir)) {
			while (($sub = readdir($handler)) !== FALSE) {
				if ($sub != "." && $sub != ".." && $sub != "Thumb.db" && $sub != "Thumbs.db" && $sub != "list") {
					if(is_file($dir."/".$sub)) {
						$listDir[] = $sub;
					}elseif(is_dir($dir."/".$sub)){
						$listDir[$sub] = $this->readFolderRecursive($dir."/".$sub);
					}
				}
			}
			closedir($handler);
		}
		return $listDir;
	}

	//recursively creates a folder.
	function mk_dir($path, $rights = 0777) {
		//$folder_path = array(strstr($path, '.') ? dirname($path) : $path);
		if (!@is_dir($path)) {
			$folder_path = array($path);
		} else {
			return;
		}

		while(!@is_dir(dirname(end($folder_path)))
		&& dirname(end($folder_path)) != '/'
		&& dirname(end($folder_path)) != '.'
		&& dirname(end($folder_path)) != ''){
			array_push($folder_path, dirname(end($folder_path)));
		}

		while($parent_folder_path = array_pop($folder_path)) {
			if(!@mkdir($parent_folder_path, $rights)) {
				user_error("Can't create folder \"$parent_folder_path\".\n");
			}
		}
	}
}

class FileException extends ErrorException{
	/**
	 * @see ErrorException
	 */
	public function __construct ($message = "", $code = 0, $severity = 1, $filename = __FILE__, $lineno = __LINE__, $previous = NULL) {
		parent::__construct($message, $code, $severity, $filename, $lineno, $previous);
	}
}

function LibraryErrorHandler($errno, $errstr, $errfile, $errline){
	if(false !== strstr($errstr, "include(")){
		throw new FileException($errstr, 0, $errno, $errfile, $errline);
	}

	throw new ErrorException($errstr, 0, $errno, $errfile, $errline);

	return true;
}